package nc.impl.hrpbm.deptbuget;

import java.sql.Types;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.ObjectUtils;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.hrpbm.deptbudget.DeptBudgetProjectAndExpenditureCollectService;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.pub.hrpbm.util.HrpbmReportUtils;
import nc.pub.smart.context.SmartContext;
import nc.pub.smart.data.DataSet;
import nc.pub.smart.metadata.Field;
import nc.pub.smart.metadata.MetaData;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nccloud.commons.lang.ArrayUtils;
import uap.lfw.bq.portal.base.StringUtils;

public class DeptBudgetProjectAndExpenditureCollectServiceImpl  implements DeptBudgetProjectAndExpenditureCollectService{
	HrpbmReportUtils Utils = new HrpbmReportUtils();
	private BaseDAO baseDAO;

	public BaseDAO getBaseDAO() {
		return baseDAO == null ? new BaseDAO() : baseDAO;
	}

	public static final String cwbudgetdeptcode = "405"; // 财务部门编码
	public static final String firstparentcode = "1"; // 收支项目: 收入科目编码

	String[] fields = new String[] { "inoutbusiclassname","deptname","nyear","f1project_name",
			"f2project_name","type_name","amount_01","amount_02","amount_03","amount_04",
			"amount_05" ,"amount","inoutbusiclasscode","fundsourceamount","f3project_name"
			,"pk_project"
	};
	String[] fieldCaptions = new String[] {"支出科目名称", "部门名称","年度", "一级项目名称",
			"二级项目名称", "项目类型","财政基本拨款经费","财政项目拨款经费","科教经费","非同级财政拨款经费","其他经费","合计" ,"科目编码","来源合计", "三级项目名称"
			,"三级项目"
	};

	@Override
	public DataSet process(SmartContext context) throws BusinessException {


		MetaData metadata = this.initMetaData();
		Utils.handelContext(context);
		List<Map<String, Object>>  sqlResult=getBusinessData(context);

		return buildDataSetobj(metadata, sqlResult, fields);
	}

	private List getBusinessData(SmartContext context) throws BusinessException {


		String pk_org = (String) context.getAttribute("pk_org");
		String budgetdept = (String) context.getAttribute("pk_budgetdept");
		String inoutlevel = (String) context.getAttribute("level");
		String pk_inoutclass = (String) context.getAttribute("pk_inoutclass");
		String pk_eps = (String) context.getAttribute("pk_eps");
		String nyear = (String) context.getAttribute("nyear");
		String isfund = (String) context.getAttribute("isfund");
		String f1project =  (String)context.getAttribute("f1project");
		String f2project = (String) context.getAttribute("f2project");
		String pk_project = (String) context.getAttribute("pk_project");

		StringBuffer sql = new StringBuffer();
		sql.append("select * from ( ");
		sql.append("SELECT DISTINCT detail.pk_inoutclass pk_inoutclass,");//
		sql.append("                inoutbusiclass.code inoutbusiclasscode,");//
		sql.append("                inoutbusiclass.pk_parent inoutbusiclassparent,");//
		sql.append("                inoutbusiclass.name inoutbusiclassname,");//
		sql.append("                budgetdept.name deptname,");//
		sql.append("                detail.nyear,");//
		sql.append("                projectclass.eps_name type_name,");//
		sql.append("                fundsource.name fundsourcename,");//
		sql.append("                taskstate,");//
		sql.append("                CASE");//
		sql.append("                  WHEN detail.amount_seconddown IS NULL THEN");//
		sql.append("                   CASE");//
		sql.append("                     WHEN detail.amount_firstdown IS NOT NULL THEN");//
		sql.append("                      detail.amount_firstdown");//
		sql.append("                   END");//
		sql.append("                  ELSE");//
		sql.append("                   detail.amount_seconddown");//
		sql.append("                END amount_firstup,");//
		sql.append("                detail.pk_budgetreplydetail,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '1' THEN");//
		sql.append("                   project.project_name");//
		sql.append("                  WHEN f2project.def1 = '1' THEN");//
		sql.append("                   f2project.project_name");//
		sql.append("                  WHEN f3project.def1 = '1' THEN");//
		sql.append("                   f3project.project_name");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END f1project_name,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '2' THEN");//
		sql.append("                   project.project_name");//
		sql.append("                  WHEN f2project.def1 = '2' THEN");//
		sql.append("                   f2project.project_name");//
		sql.append("                  WHEN f3project.def1 = '2' THEN");//
		sql.append("                   f3project.project_name");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END f2project_name,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '3' THEN");//
		sql.append("                   project.project_name");//
		sql.append("                  WHEN f2project.def1 = '3' THEN");//
		sql.append("                   f2project.project_name");//
		sql.append("                  WHEN f3project.def1 = '3' THEN");//
		sql.append("                   f3project.project_name");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END f3project_name,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '1' THEN");//
		sql.append("                   project.pk_project");//
		sql.append("                  WHEN f2project.def1 = '1' THEN");//
		sql.append("                   f2project.pk_project");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END pk_f1project,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '2' THEN");//
		sql.append("                   project.pk_project");//
		sql.append("                  WHEN f2project.def1 = '2' THEN");//
		sql.append("                   f2project.pk_project");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END pk_f2project,");//
		sql.append("                fundsource.code fundsourcecode,");//
		sql.append("                detail.pk_project,");//
		sql.append("                doc.code || '-' || doc.name projectname");//
		sql.append("  FROM hrpbm_budgetreplydetail detail");//
		sql.append("  LEFT JOIN hrpbm_budgetreply make");//
		sql.append("    ON make.pk_budgetreply = detail.pk_budgetreply");//
		sql.append("  LEFT JOIN bd_fundsource fundsource");//
		sql.append("    ON fundsource.pk_fundsource = detail.pk_fundsource");//
		sql.append("  LEFT JOIN hrppl_pjappl pjappl");//
		sql.append("    ON pjappl.pk_pjappl = detail.pk_project");//
		sql.append("  LEFT JOIN (SELECT pk_defdoc, name, code");//
		sql.append("               FROM bd_defdoc");//
		sql.append("              WHERE pk_defdoclist = '1001YY100000000EMU3T') doc");//
		sql.append("    ON doc.pk_defdoc = pjappl.functionsubject");//
		sql.append("  LEFT JOIN bd_project project");//
		sql.append("    ON detail.pk_project = project.pk_project");//
		sql.append("  LEFT JOIN hrpbm_budgetdept budgetdept");//
		sql.append("    ON budgetdept.pk_budgetdept = make.pk_budgetdept");//
		sql.append("  LEFT JOIN pm_eps projectclass");//
		sql.append("    ON project.pk_eps = projectclass.pk_eps");//
		sql.append("  LEFT JOIN bd_project f2project");//
		sql.append("    ON f2project.pk_project = project.pk_parentpro");//
		sql.append("  LEFT JOIN bd_project f3project");//
		sql.append("    ON f2project.pk_project = f3project.pk_parentpro");//
		sql.append("  LEFT JOIN bd_inoutbusiclass inoutbusiclass");//
		sql.append("    ON inoutbusiclass.pk_inoutbusiclass = detail.pk_inoutclass");//
		sql.append(" WHERE 1 = 1");//
		sql.append("   AND detail.nyear = '"+nyear+"'");
		sql.append("   AND make.transtype = 'BM25-Cxx-CD-YS02'");//
		sql.append("   AND taskstate = 6 " );

		if (StringUtils.isNotBlank(pk_inoutclass)) {
			String pk_inoutclassInString = convertToInClause(pk_inoutclass);
			sql.append("   AND detail.pk_inoutclass in (" + pk_inoutclassInString + ") \n");
		}

		if (StringUtils.isNotBlank(pk_org) && !"GLOBLE00000000000000".equals(pk_org)) {
			sql.append("   AND detail.pk_org = '" + pk_org + "' \n");// 财务组织
		}

		if (StringUtils.isNotBlank(nyear) && "2025".equals(nyear)){
			sql.append("   AND budgetdept.pk_budgetdept not in ('1001A21000000006A8GP') \n");// 设备物资部
		}

		if (StringUtils.isNotBlank(budgetdept)) {
			String pk_budgetdeptInString = convertToInClause(budgetdept);
			sql.append("   AND make.pk_budgetdept  in (" + pk_budgetdeptInString + ") \n");// 预算科室
		}

		if (StringUtils.isNotBlank(pk_eps)) {
			String pk_epss = convertToInClause(pk_eps);
			sql.append("   AND project.pk_eps in (" + pk_epss + ") \n");// 项目类型
		}

		sql.append(" UNION ALL ");//
		sql.append("SELECT DISTINCT detail.pk_inoutclass pk_inoutclass,");//
		sql.append("                inoutbusiclass.code inoutbusiclasscode,");//
		sql.append("                inoutbusiclass.pk_parent inoutbusiclassparent,");//
		sql.append("                inoutbusiclass.name inoutbusiclassname,");//
		sql.append("                budgetdept.name deptname,");//
		sql.append("                detail.nyear,");//
		sql.append("                projectclass.eps_name type_name,");//
		sql.append("                fundsource.name fundsourcename,");//
		sql.append("                taskstate,");//
		sql.append("                CASE");//
		sql.append("                  WHEN detail.amount_seconddown IS NULL THEN");//
		sql.append("                   CASE");//
		sql.append("                     WHEN detail.amount_firstdown IS NOT NULL THEN");//
		sql.append("                      detail.amount_firstdown");//
		sql.append("                   END");//
		sql.append("                  ELSE");//
		sql.append("                   detail.amount_seconddown");//
		sql.append("                END amount_firstup,");//
		sql.append("                detail.pk_budgetreplydetail,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '1' THEN");//
		sql.append("                   project.project_name");//
		sql.append("                  WHEN f2project.def1 = '1' THEN");//
		sql.append("                   f2project.project_name");//
		sql.append("                  WHEN f3project.def1 = '1' THEN");//
		sql.append("                   f3project.project_name");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END f1project_name,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '2' THEN");//
		sql.append("                   project.project_name");//
		sql.append("                  WHEN f2project.def1 = '2' THEN");//
		sql.append("                   f2project.project_name");//
		sql.append("                  WHEN f3project.def1 = '2' THEN");//
		sql.append("                   f3project.project_name");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END f2project_name,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '3' THEN");//
		sql.append("                   project.project_name");//
		sql.append("                  WHEN f2project.def1 = '3' THEN");//
		sql.append("                   f2project.project_name");//
		sql.append("                  WHEN f3project.def1 = '3' THEN");//
		sql.append("                   f3project.project_name");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END f3project_name,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '1' THEN");//
		sql.append("                   project.pk_project");//
		sql.append("                  WHEN f2project.def1 = '1' THEN");//
		sql.append("                   f2project.pk_project");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END pk_f1project,");//
		sql.append("                CASE");//
		sql.append("                  WHEN project.def1 = '2' THEN");//
		sql.append("                   project.pk_project");//
		sql.append("                  WHEN f2project.def1 = '2' THEN");//
		sql.append("                   f2project.pk_project");//
		sql.append("                  ELSE");//
		sql.append("                   NULL");//
		sql.append("                END pk_f2project,");//
		sql.append("                fundsource.code fundsourcecode,");//
		sql.append("                detail.pk_project,");//
		sql.append("                doc.code || '-' || doc.name projectname");//
		sql.append("  FROM hrpbm_budgetreplydetail detail");//
		sql.append("  LEFT JOIN hrpbm_budgetreply make");//
		sql.append("    ON make.pk_budgetreply = detail.pk_budgetreply");//
		sql.append("  LEFT JOIN bd_fundsource fundsource");//
		sql.append("    ON fundsource.pk_fundsource = detail.pk_fundsource");//
		sql.append("  LEFT JOIN hrppl_pjappl pjappl");//
		sql.append("    ON pjappl.pk_pjappl = detail.pk_project");//
		sql.append("  LEFT JOIN (SELECT pk_defdoc, name, code");//
		sql.append("               FROM bd_defdoc");//
		sql.append("              WHERE pk_defdoclist = '1001YY100000000EMU3T') doc");//
		sql.append("    ON doc.pk_defdoc = pjappl.functionsubject");//
		sql.append("  LEFT JOIN bd_project project");//
		sql.append("    ON detail.pk_project = project.pk_project");//
		sql.append("  LEFT JOIN hrpbm_budgetdept budgetdept");//
		sql.append("    ON budgetdept.pk_budgetdept = make.pk_budgetdept");//
		sql.append("  LEFT JOIN pm_eps projectclass");//
		sql.append("    ON project.pk_eps = projectclass.pk_eps");//
		sql.append("  LEFT JOIN bd_project f2project");//
		sql.append("    ON f2project.pk_project = project.pk_parentpro");//
		sql.append("  LEFT JOIN bd_project f3project");//
		sql.append("    ON f2project.pk_project = f3project.pk_parentpro");//
		sql.append("  LEFT JOIN bd_inoutbusiclass inoutbusiclass");//
		sql.append("    ON inoutbusiclass.pk_inoutbusiclass = detail.pk_inoutclass");//
		sql.append(" WHERE 1 = 1");//
		sql.append("   AND detail.nyear = '"+nyear+"'");
		sql.append("   AND make.transtype = 'BM25-Cxx-CD-YS03'");//
		sql.append("   AND taskstate = 13 ");

//		if(isfund!=null) {
//			sql.append( " and fip_docview_b.code3 = '"+isfund+"'");
//		}

		if (StringUtils.isNotBlank(pk_inoutclass)) {
			String pk_inoutclassInString = convertToInClause(pk_inoutclass);
			sql.append("   AND detail.pk_inoutclass in (" + pk_inoutclassInString + ") \n");
		}

		if (StringUtils.isNotBlank(pk_org) && !"GLOBLE00000000000000".equals(pk_org)) {
			sql.append("   AND detail.pk_org = '" + pk_org + "' \n");// 财务组织
		}

		if (StringUtils.isNotBlank(budgetdept)) {
			String pk_budgetdeptInString = convertToInClause(budgetdept);
			sql.append("   AND make.pk_budgetdept  in (" + pk_budgetdeptInString + ") \n");// 预算科室
		}

		if (StringUtils.isNotBlank(pk_eps)) {
			String pk_epss = convertToInClause(pk_eps);
			sql.append("   AND project.pk_eps in (" + pk_epss + ") \n");// 项目类型
		}

		sql.append(") aa where 1=1");
		if (StringUtils.isNotBlank(f1project)) {
			String f1projectStr = convertToInClause(f1project);
			sql.append("   AND aa.pk_f1project in (" + f1projectStr + ") \n");// 预算科室
		}
		if (StringUtils.isNotBlank(f2project)) {
			String f2projectStr = convertToInClause(f2project);
			sql.append("   AND aa.pk_f2project in (" + f2projectStr + ") \n");// 预算科室
		}

		if (StringUtils.isNotBlank(pk_project)) {
			String f3projectStr = convertToInClause(pk_project);
			sql.append("   AND aa.pk_project in (" + f3projectStr + ") \r\n");// 预算科室
		}

		//sql.append(" order by DEPTNAME asc");

		List<Map<String,Object>> list = (ArrayList<Map<String,Object>>)getBaseDAO().executeQuery(sql.toString(), new MapListProcessor());
		//initFundsource(list);
		List<Map<String,Object>> newList = new ArrayList();



		initListByfundsource(list);
		//获取上级分类
		//根据项目分类，一二级项目 将相同项 收入金额改为所有相同项的合计
		List<Map<String,Object>> listToCopyInto = new ArrayList<>();
		listToCopyInto = ObjectUtils.clone(list);
		//	List<Map<String,Object>> list1 = initnewList(initList(list,newList));
		//计算部门合计
		//	List<Map<String,Object>> listinitInto=initdeptList(list1,listToCopyInto);



		//	listToCopyInto.addAll(listinitInto);


		return listToCopyInto;
	}
	private Field[] initField() {
		Field[] FieldInfo = new Field[fields.length];
		for (int i = 0; i < fields.length; i++) {
			Field filed = new Field();
			filed.setCaption(fieldCaptions[i]);
			filed.setDbColumnType(Types.VARCHAR);
			if (i == 6 || i == 7|| i == 8|| i == 9|| i == 10|| i == 11|| i==13) { // 5,7对应编制金额，批复金额，金额是否需要调整字段类型，根据情况定
				filed.setDbColumnType(Types.DECIMAL);
				filed.setPrecision(28);
				filed.setScale(2);
			}

			filed.setFldname(fields[i]);
			if (i == 3 || i == 4 || i == 14|| i == 15) {// 视情况而定
				filed.setPrecision(200);
				filed.setDbColumnType(Types.VARCHAR);
			}
			FieldInfo[i] = filed;
		}
		return FieldInfo;
	}
	/**
	 * 	初始化metadata
	 * @return
	 */
	private MetaData initMetaData() {
		Field[] FieldInfo = initField();
		MetaData md = new MetaData();
		for (int i = 0; i < fields.length; i++) {
			md.addField(FieldInfo[i]);
		}
		return md;
	}
	public static DataSet buildDataSetobj(MetaData meta, List<Map<String, Object>> list, String[] fields) {
		if (ArrayUtils.isEmpty(fields)) {
			ExceptionUtils.wrappBusinessException("报表字段列不能为空，请检查！！！");
		}
		DataSet ds = null;
		if (null == list || list.size() == 0) {
			// 返回空数据集, 用于给语义模型加载空数据用
			Object[][] datas = new Object[1][fields.length];
			ds = new DataSet(meta, datas);
		} else {
			Object[][] datas = new Object[list.size()][fields.length];
			for(int i = 0;i < list.size();i++){
				for(int j = 0; j < fields.length; j++ ) {
					datas[i][j] = list.get(i).get(fields[j].toString());
					//vos[i].getAttributeValue(fields[j]);
				}
			}
			ds = new DataSet(meta, datas);
		}
		return ds;
	}

	public static String convertToInClause(String value) {
		if(StringUtils.isBlank(value)) {
			return "";
		}
		String[] values = value.split(",");

		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < values.length; i++) {
			sb.append('\'').append(values[i]).append('\'');
			if (i < values.length - 1) {
				sb.append(',');
			}
		}
		return sb.toString();
	}
	public List<Map<String,Object>> initListByfundsource(List<Map<String,Object>> list) {

		List<Map<String,Object>> initlist = new ArrayList();

		for (Map map : list) {

			//  Map<String,Object> map1 = new HashMap();

			map.put("oneup_01", Double.valueOf(0));
			map.put("oneup_02",Double.valueOf(0));
			map.put("oneup_03",Double.valueOf(0));
			map.put("oneup_04",Double.valueOf(0));
			map.put("oneup_05",Double.valueOf(0));

			Double amount =0.00;
			amount += map.get("amount_firstup")==null?0.00:((Number) map.get("amount_firstup")).doubleValue();
			String sourcecode= map.get("fundsourcecode").toString();
			map.put("oneup_"+sourcecode, map.get("amount_firstup")==null?0:map.get("amount_firstup"));


			// map1.put("number", i++);
			map.put("amount", amount);
			initlist.add(map);

		}
//		 Map<String, List<Map<String, Object>>> groupedByCategoryAndType = initlist.stream().collect
//							(Collectors.groupingBy(
//	                        map -> map.get("inoutbusiclassname").toString()
//	                        + "-"+map.get("type_name")
//	                        + "-"+map.get("f1project_name")+ "-"+map.get("f2project_name")+ "-"+map.get("f3project_name")))
//	                       // 创建一个复合键
//					;
		// 谁写的石山代码 我真的要骂娘了⬆
		// 使用主键作为分组键（确保唯一性）
		Map<String, List<Map<String, Object>>> groupedByCategoryAndType = initlist.stream()
				.collect(Collectors.groupingBy(
						map -> map.get("pk_budgetreplydetail").toString() // 用主键字段[4,1](@ref)
				));

		for (Entry<String, List<Map<String, Object>>> entry : groupedByCategoryAndType.entrySet()) {
			List<Map<String, Object>> value =  entry.getValue();

			Double amount_01 =0.00;
			Double amount_02 =0.00;
			Double amount_03 =0.00;
			Double amount_04 =0.00;
			Double amount_05 =0.00;
			for(Map<String, Object> map:value) {
				amount_01 += map.get("oneup_01")==null?0.00:((Number) map.get("oneup_01")).doubleValue();
				amount_02 += map.get("oneup_02")==null?0.00:((Number) map.get("oneup_02")).doubleValue();
				amount_03 += map.get("oneup_03")==null?0.00:((Number) map.get("oneup_03")).doubleValue();
				amount_04 += map.get("oneup_04")==null?0.00:((Number) map.get("oneup_04")).doubleValue();
				amount_05 += map.get("oneup_05")==null?0.00:((Number) map.get("oneup_05")).doubleValue();

			}
			for(Map<String, Object> map:value) {
				map.put("amount_01",amount_01);
				map.put("amount_02",amount_02);
				map.put("amount_03",amount_03);
				map.put("amount_04",amount_04);
				map.put("amount_05",amount_05);
				map.put("fundsourceamount",amount_01+amount_02+amount_03+amount_04+amount_05);
			}
		}



		return initlist;

	}
	private List<Map<String,Object>> initList(List<Map<String,Object>> list,List<Map<String,Object>> newlist) throws DAOException {

		//获取上级

		//根据上级分组
		Map<String, List<Map<String, Object>>> grouped = list.stream()
				.collect(Collectors.groupingBy(
						map -> map.get("inoutbusiclassparent")==null?"top":(String)map.get("inoutbusiclassparent"), // 分组键
						Collectors.toList() // 收集器，这里简单地将元素放入列表中
				));

		List getList = new ArrayList();


		for (Object key : grouped.keySet()) {
			if(!"top".equals(key)) {

				List<Map<String,Object>> groupedList =grouped.get(key);
				Map<String,Object> newMap = new HashMap<String,Object>();
				//     	 newMap = groupedList.get(0);
				//计算总值
				Double sum = 0.00;
				Double oneup_01Sum = 0.00, oneup_02Sum = 0.00, oneup_03Sum = 0.00, oneup_04Sum = 0.00, oneup_05Sum = 0.00;
//   	        	Double twoup_01Sum = 0.00, twoup_02Sum = 0.00, twoup_03Sum = 0.00, twoup_04Sum = 0.00, twoup_05Sum = 0.00;
//   	        	Double onedown_01Sum = 0.00, onedown_02Sum = 0.00, onedown_03Sum = 0.00, onedown_04Sum = 0.00, onedown_05Sum = 0.00;
//   	        	Double twodown_01Sum = 0.00, twodown_02Sum = 0.00, twodown_03Sum = 0.00, twodown_04Sum = 0.00, twodown_05Sum = 0.00;
				//获取上级编码
				String sql = "select code inoutbusiclasscode,pk_parent inoutbusiclassparent,name inoutbusiclassname,pk_inoutbusiclass pk_inoutclass,def1 classlevel  "
						+ "from bd_inoutbusiclass where pk_inoutbusiclass='"+key.toString()+"'";
				Map<String,Object> fatherMap = (Map<String,Object>)getBaseDAO().executeQuery(sql, new MapProcessor());
				for(Map map: groupedList) {





					//计算列和
					if ( map.get("oneup_01") instanceof Number) {
						oneup_01Sum += ((Number) map.get("oneup_01")).doubleValue();
					}
					if ( map.get("oneup_02") instanceof Number) {
						oneup_02Sum += ((Number) map.get("oneup_02")).doubleValue();
					}
					if ( map.get("oneup_03") instanceof Number) {
						oneup_03Sum += ((Number) map.get("oneup_03")).doubleValue();
					}
					if ( map.get("oneup_04") instanceof Number) {
						oneup_04Sum += ((Number) map.get("oneup_04")).doubleValue();
					}
					if ( map.get("oneup_05") instanceof Number) {
						oneup_05Sum += ((Number) map.get("oneup_05")).doubleValue();
					}



				}
				newMap.put("amount_01",oneup_01Sum);

				newMap.put("amount_02",oneup_02Sum);

				newMap.put("amount_03",oneup_03Sum);

				newMap.put("amount_04",oneup_04Sum);

				newMap.put("amount_05",oneup_05Sum);


				newMap.put("oneup_01",oneup_01Sum);

				newMap.put("oneup_02",oneup_02Sum);

				newMap.put("oneup_03",oneup_03Sum);

				newMap.put("oneup_04",oneup_04Sum);

				newMap.put("oneup_05",oneup_05Sum);

				if(fatherMap!=null) {
					newMap.put("inoutbusiclassname",fatherMap.get("inoutbusiclassname"));
					newMap.put("inoutbusiclasscode",fatherMap.get("inoutbusiclasscode"));
					newMap.put("inoutbusiclassparent",fatherMap.get("inoutbusiclassparent"));
					newMap.put("pk_inoutclass",fatherMap.get("pk_inoutclass"));
					//	newMap.put("classlevel",fatherMap.get("classlevel"));
					newMap.put("f1project_name",groupedList.get(0).get("f1project_name"));
					newMap.put("f2project_name",groupedList.get(0).get("f2project_name"));
					newMap.put("f3project_name",groupedList.get(0).get("f3project_name"));
					newMap.put("type_name",groupedList.get(0).get("type_name"));
					newMap.put("nyear",groupedList.get(0).get("nyear"));

				}
				//计算合计
				newMap.put("fundsourceamount",oneup_01Sum+oneup_02Sum+oneup_03Sum+oneup_04Sum+oneup_05Sum);



				newlist.add(newMap);
				getList.add(newMap);
			}
		}

		list.addAll(getList);


		if(!getList.isEmpty()) {
			initList(getList,newlist);


		}

		return newlist;



	}

	private List<Map<String,Object>> initnewList(List<Map<String,Object>> list){
		List<Map<String, Object>> returnList =  new ArrayList();
		Map<String, List<Map<String, Object>>> grouped = list.stream()
				.collect(Collectors.groupingBy(
						map -> map.get("pk_inoutclass").toString(),// 分组键
						Collectors.toList() // 收集器，这里简单地将元素放入列表中
				));
		for (Object key : grouped.keySet()) {

			List<Map<String, Object>> groupedList= grouped.get(key);
			//key相同的项进行合并
			Double sum = 0.00;
			Double oneup_01Sum = 0.00, oneup_02Sum = 0.00, oneup_03Sum = 0.00, oneup_04Sum = 0.00, oneup_05Sum = 0.00;


			for(Map map:groupedList) {

				//计算列和
				if ( map.get("amount_01") instanceof Number) {
					oneup_01Sum += ((Number) map.get("amount_01")).doubleValue();
				}
				if ( map.get("amount_02") instanceof Number) {
					oneup_02Sum += ((Number) map.get("amount_02")).doubleValue();
				}
				if ( map.get("amount_03") instanceof Number) {
					oneup_03Sum += ((Number) map.get("amount_03")).doubleValue();
				}
				if ( map.get("amount_04") instanceof Number) {
					oneup_04Sum += ((Number) map.get("amount_04")).doubleValue();
				}
				if ( map.get("amount_05") instanceof Number) {
					oneup_05Sum += ((Number) map.get("amount_05")).doubleValue();
				}



			}
			Map<String,Object> newMap = new HashMap();
			newMap.put("amount_01",oneup_01Sum);

			newMap.put("amount_02",oneup_02Sum);

			newMap.put("amount_03",oneup_03Sum);

			newMap.put("amount_04",oneup_04Sum);

			newMap.put("amount_05",oneup_05Sum);


			newMap.put("inoutbusiclassname",groupedList.get(0).get("inoutbusiclassname"));
			newMap.put("inoutbusiclasscode",groupedList.get(0).get("inoutbusiclasscode"));
			newMap.put("inoutbusiclassparent",groupedList.get(0).get("inoutbusiclassparent"));
			newMap.put("pk_inoutclass",groupedList.get(0).get("pk_inoutclass"));
			newMap.put("f1project_name",groupedList.get(0).get("f1project_name"));
			newMap.put("f2project_name",groupedList.get(0).get("f2project_name"));
			newMap.put("f3project_name",groupedList.get(0).get("f3project_name"));
			newMap.put("type_name",groupedList.get(0).get("type_name"));
			newMap.put("deptname",groupedList.get(0).get("deptname"));
			newMap.put("amount",groupedList.get(0).get("amount"));
			newMap.put("nyear",groupedList.get(0).get("nyear"));
//	        	
			//计算合计
			newMap.put("fundsourceamount",oneup_01Sum+oneup_02Sum+oneup_03Sum+oneup_04Sum+oneup_05Sum);


			returnList.add(newMap);
			//  list.add(newMap);

		}




		return returnList;

	}
	private List<Map<String,Object>> initdeptList(List<Map<String,Object>> list,List<Map<String,Object>> newlist){
		//根据组织和
		List<Map<String,Object>> returnlist = new ArrayList();
		List<Map<String,Object>> firstlist = new ArrayList();
		for(Map map :list) {
			//获取子集

//			 List<Map<String, Object>> filteredList = newlist.stream()  
//					 .filter(map1 -> map1.containsKey("inoutbusiclassparent") && map1.get("inoutbusiclassparent").equals(map.get("pk_inoutclass")))  
//					 .collect(Collectors.toList());

			List<Map<String, Object>> filteredList = newlist.stream()
					.filter(filteredListmap -> {
						String code = (String) filteredListmap.get("inoutbusiclasscode");
						return code != null && code.startsWith(map.get("inoutbusiclasscode").toString());
					})
					.collect(Collectors.toList());

			if(!filteredList.isEmpty()) {
				map.put("istop", "1");
			}
			Map<String, List<Map<String, Object>>> deptgrouped = filteredList.stream()
					.collect(Collectors.groupingBy(
							map2 ->(String) map2.get("deptname"), // 分组键
							Collectors.toList() // 收集器，这里简单地将元素放入列表中
					));
			for (Entry<String, List<Map<String, Object>>> entry : deptgrouped.entrySet()) {
				Map<String, Object> newMap =  new HashMap();
				String deptName = entry.getKey(); // 部门名称
				List<Map<String, Object>> employees = entry.getValue(); // 该部门下的所有员工信息
				Double amount = 0.00;
				for(Map map3:employees) {
					if ( map3.get("amount_firstup") instanceof Number) {
						amount += ((Number) map3.get("amount_firstup")).doubleValue();
					}

				}
				newMap.putAll(map);
				newMap.put("deptname",deptName);
				newMap.put("amount",amount);
				newMap.put("istop","1");
				firstlist.add(newMap);

			}

		}
		List<Map<String,Object>> listToCopyInto = new ArrayList<>();
		listToCopyInto = ObjectUtils.clone(firstlist);
		//initdeptList1(list,firstlist);
		return firstlist;

		//首次


	}
	private List<Map<String,Object>> initdeptList1(List<Map<String,Object>> list,List<Map<String,Object>> newlist){
		//根据组织和
		List<Map<String,Object>> returnlist = new ArrayList();
		for(Map map :list) {
			//获取子集
			if(!map.containsKey("istop")) {

				List<Map<String, Object>> filteredList = newlist.stream()
						.filter(map1 -> {
							// 确保map1不为null且包含指定的键，并且其值也不为null
							if (map1 != null && map1.containsKey("inoutbusiclassparent")) {
								Object parentClass = map1.get("inoutbusiclassparent");
								// 确保map不为null且包含指定的键，并且其值也不为null
								if (map != null && map.containsKey("pk_inoutclass")) {
									Object pkClass = map.get("pk_inoutclass");
									// 现在可以安全地比较这两个值了
									return parentClass != null && parentClass.equals(pkClass);
								}
							}
							// 如果不满足条件，返回false
							return false;
						})
						.collect(Collectors.toList());
				if(!filteredList.isEmpty()) {
					map.put("istop", "1");
				}
				Map<String, List<Map<String, Object>>> deptgrouped = filteredList.stream()
						.collect(Collectors.groupingBy(
								map2 ->(String) map2.get("deptname"), // 分组键
								Collectors.toList() // 收集器，这里简单地将元素放入列表中
						));
				for (Entry<String, List<Map<String, Object>>> entry : deptgrouped.entrySet()) {
					Map<String, Object> newMap =  new HashMap();
					String deptName = entry.getKey(); // 部门名称
					List<Map<String, Object>> employees = entry.getValue(); // 该部门下的所有员工信息
					Double amount = 0.00;
					for(Map map3:employees) {
						if ( map3.get("amount") instanceof Number) {
							amount += ((Number) map3.get("amount")).doubleValue();
						}

					}
					newMap.putAll(map);
					newMap.put("deptname",deptName);
					newMap.put("amount",amount);
					newMap.put("istop","1");
					newlist.add(newMap);

				}

			}
		}
		List<Map<String, Object>> filteredList = list.stream()
				.filter(listmap -> !listmap.containsKey("istop") )
				.collect(Collectors.toList());
		if(!filteredList.isEmpty()) {
			initdeptList(list,returnlist);
		}
		return newlist;

		//首次


	}

}
